home *** CD-ROM | disk | FTP | other *** search
-
- SHARED_LIB EXAMPLE CODE
-
- This is a fully compilable shared library implemented for DICE
- demonstrating how one can write their very own shared library. Some
- knowledge in shared libraries is required to understand the code..
- the basic thing to remember is (1) that a shared library is NOT a
- normal C program, and (2) the interface calls MUST be reentrant...
- i.e. multiple tasks can make a library call simultaniously.
-
- The only limitation with this example is that I use -mRR which turns on
- registered arguments. The limitation is that currently DICE will only
- generated registered functions for those routines that take no more
- than 2 integers and 2 pointers. Routines that take more than that
- limit or take other types (structures, floating pt, etc...) will
- not have a registered entry point.
-
- SHARED LIBRARY
-
- DEFS.H contains header stuff
- TAG.A library independant basic code
- LIB.C library independant basic code
- INIT.C library dependant initialization routines
- FUNCS.C library dependant routines
-
- TAG.A and LIB.C are almost self contained with only a few modifications
- required to use them for other library projects... basically the
- name of the library in TAG.A and the function list in LIB.C
-
- TAG.A contains a subset of the standard startup code, LIB/AMIGA/C.A,
- and assumes non-resident compilation (i.e. you cannot use the -r
- option). This isn't a problem since the -r option doesn't gain you
- anything as far as shared libraries go.
-
- The individual library interface routines are declared with the LibCall
- macro, defined in DEFS.H, which ensures the small-data pointer is set
- up for all interface calls allowing use of the small-data model.
-
- LIBRARY INTERFACE
-
- LIB.FD The .FD file must match library prototypes. The first two
- integer arguments are stuck in D0 & D1 while the first
- two pointer arguments are stuck in A0 & A1.
-
- AUTO.A This is extremely DICE specific in that it gives programs
- that link with the interface .lib (link library) the
- capability to auto-open & close test.library without
- having to explicitly do so in main().
-
- Notice that test.c doesn't explicitly OpenLibrary() or
- CloseLibrary() "test.library". DICE provides such
- capabilities for most standard amiga libraries in the
- same fashion.
-
- ---
-
- To compile, be sure that -2.0 is specified in your DCCOPTS an the
- 2.0 registered libraries are unpacked:
-
- DLIB:amigasr20.lib
- DLIB:cr.lib
-
- DINCLUDE:AMIGA20/*/*.h
-
- Create a temporary directory to hold the resulting objects and the
- resulting .lib tag library. The resulting .library file will be placed
- in LIBS: and the test program will be T:test
-
- DTMP:sharlib/ (to hold the objects & .lib file)
-
- Note that you will get warnings from FDTOLIB, these can be ignored. A
- non-registered and registered version of the interface link library
- required when linking TEST.C is generated, and two versions of TEST.C
- are included to show what is required to compile either a normal
- program or registered-args program that talks to the registered-args
- library.
-
- 1> dmake
- ... compiles it all ...
- 1> test.script
-
-
- THE LINK LIB
-
- You will notice that the test program must be linked with test.lib
- from DTMP:sharlib/ .. this is the library interface tag library
- which interfaces C calls to a shared library. Under DICE, a twist
- is added in the form of a special auto-open module appended to the
- .lib file.
-
- This auto-open module allows the TEST program to make library calls
- without explicitly openning the shared library! This greatly simplifies
- the complication that using shared libraries generally adds.
-
- If you are interested, you should run 'DOBJ DTMP:SHARLIB/TEST.LIB' to
- see how the link library works.
-
- ORDERING OF REGISTERED ARGUMENTS
-
- Arguments to registered calls work as follows:
-
- if (number of args <= 4 && not var-args-call && only int & ptr args)
- put arguments in registers
- else
- use stack call
-
- Registers are assigned to arguments in argument order. Integers are
- assigned to D0 and D1 if available at the point they are scanned, else
- A0 then A1 will be used (again, if not already assigned). Pointers
- are assigned to A0 and A1 if available at the point they are scanned,
- else D0 then D1 will be used (again, if not already assigned to a
- previous argument).
-
- (a few examples of register ordering)
-
- fubar(int, char *, int, char *)
- D0 A0 D1 A1
-
- fubar(char *, int, char *, int)
- A0 D0 A0 D0
-
- fubar(char *, int, int, int)
- A0 D0 D1 A1
-
- fubar(int, int, int, char *)
- D0 D1 A0 A1 <---- note!
-
- fubar(char *, char *, char *, int)
- A0 A1 D0 D1 <---- note!
-
- You need to know the register ordering to construct your .FD file
- properly.
-
-
- NOT USING REGISTERED ARGUMENTS
-
- When you are not using registered arguments you will still want
- the library to be called with arguments in registers. However,
- since your library routine does not use registered arguments you
- will need to create an assembly tag in TAG.A to deal with it, then
- have your function array in LIB.C point to the tags instead of the
- actual library functions.
-
- Example: if you have a routine called 'MyLibCall' in C, it's
- symbol in assembly would be _MyLibCall. The easiest thing to do
- then is in lib.c change the MyLibCall function pointer to Asm_MyLibCall
- and in assembly write the following:
-
- xdef _Asm_MyLibCall ; assembly tag
- xref _MyLibCall ; C stack call
-
- _Asm_MyLibCall movem.l D0/D1,-(sp) ; push registers
- jsr _MyLibCall(pc)
- addq.l #8,sp
- rts
-
- Be extremely careful pushing registers, MOVEM always orders registers
- being pushed D0..D7,A0..A7, you cannot specify the order in the MOVEM
- call and may have to resort to several MOVE calls to accomplish your
- task. You do not have to restore the registers since only A2-A6/D2-D7
- are required to be left alone, and the C function will do this
- automatically, so in the example above I simply addq.l #8,sp to pop
- the stack back up (if more than 8 bytes use lea XX(sp),sp).
-
- Complex libraries with complex calls may be easier to write if you
- use assembly tags and not rely on registered arguments for the
- library routines themselves. Actually, the best way is to use
- reg-args for those library calls that fit the requirements and
- tags for those that do not, but this can be complicated and should
- not be tried unless you are an experienced C programmer.
-
- -------------------------------------------------------------------
-
- version 1
- Fixed bug in open if error occurs openning librariies... accidently
- put garbage into A7 before returning. Oops
-
- version 0
- Initial release of example
-
-
-